<?php
/**
 * Date: 2024.8
 * Author: kahn
 */
namespace service\uc;

use cache\JwtCache;
use config\Response;
use driver\ThinkOrm;
use Log;
use models\uc\LoginLogModel;
use models\uc\LogoffLogModel;
use models\uc\OauthModel;
use models\uc\RegisterLogModel;
use models\uc\UserModel;
use models\vip\UserModel as VipUserModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class UserService{

    /**
     * 登录/注册
     * @param $mobile
     * @param $loginType
     * @param $userId
     * @param $token
     * @param null $onRegisterFunc
     * @return int
     */
    static function login($mobile, $loginType, &$userId, &$token, $onRegisterFunc=null): int
    {
        $userId = 0;
        $user = UserModel::where('mobile',$mobile)->findOrEmpty();
        if(!$user->isEmpty()){
            $userId = $user->id;
            if(!self::check($user,$retCode)){
                return $retCode;
            }
        }

        $user->startTrans();
        $retCode = Response::SYSTEM_ERROR;
        try{
            if($user->isEmpty()){ //用户不存在, 执行注册
                if(!self::register($mobile, $loginType, $userId)){
                    throw new \Exception("error on register user mobile:$mobile, type:$loginType");
                }
            }

            //插入不同的注册方式需要执行的数据入库函数
            if($onRegisterFunc && !$onRegisterFunc($userId)){
                throw new \Exception("error on login call callback mobile:$mobile, callback: $onRegisterFunc");
            }

            //登陆,记录日志,生成token
            if(!self::doLogin($userId, $loginType, $token)){
                throw new \Exception("login error userId: $userId");
            }
            $user->commit();

            return Response::SUCCESS;
        }catch (\Exception $e){
            \Log::error("exception on login message", $e->getMessage());
            $user->rollBack();
            return $retCode;
        }
    }

    /**
     * 是否可以登录
     * @param $user ThinkOrm
     * @param $retCode
     * @return bool
     */
    public static function check(ThinkOrm $user, &$retCode): bool
    {
        if($user->logoff == UserModel::LOGOFF_YES){
            $retCode = Response::USER_LOGOFF;
            return false;
        }

        if($user->status == UserModel::STATUS_FREEZE){
            $retCode = Response::USER_FREEZED;
            return false;
        }
        return true;
    }

    /**
     * 记录登录日志, 设置token
     * @param $userId
     * @param $loginType
     * @param $token
     * @return bool
     */
    public static function doLogin($userId, $loginType, &$token): bool
    {
        if(!self::loginLog($userId, $loginType)){
            \Log::error("save login log error userId:$userId, login type:$loginType");
            return false;
        }

        $token = JwtService::generateJWT($userId);
        if(!$token){
            \Log::error("generate token error userId:$userId");
            return false;
        }

        return true;
    }

    /**
     * 注册账号
     * @param $mobile
     * @param $regType
     * @param $userId
     * @return bool
     */
    public static function register($mobile, $regType, &$userId): bool
    {
        $user = UserModel::create(['mobile'=>$mobile]);
        if($user->isEmpty()){
            return false;
        }else{
            $userId = $user->id;
            return (new RegisterLogModel())->save(['userId'=>$userId, 'type'=>$regType]);
        }

    }

    /**
     * 登录log
     * @param $userId
     * @param $loginType
     * @return bool
     */
    public static function loginLog($userId, $loginType): bool
    {
        return (new LoginLogModel())->save(['userId'=>$userId, 'type'=>$loginType]);
    }

    /**
     * 注销
     * @param $user ThinkOrm
     * @return string
     */
    public static function logoff(ThinkOrm $user): string
    {
        $user->startTrans();
        try{
            //设置手机号为null, 设置logoff状态
            $user->mobile = null;
            $user->logoff = UserModel::LOGOFF_YES;
            if (!$user->save()){
                throw new \Exception('user表logoff失败');
            }
            //清除token
            if (!(new JwtCache())->logoff($user->id)){
                throw new \Exception('token清除失败');
            }
            //清除第三方登录绑定关系
            $oauth = OauthModel::where('userId', $user->id)->findOrEmpty();
            if(!$oauth->isEmpty()){
                $oauth->unionId = null;
                if(!$oauth->save()){
                    throw new \Exception('第三方绑定关系清除失败');
                }
            }
            //记录注销log
            $logoffLog = LogoffLogModel::create(['userId'=>$user->id]);
            if($logoffLog->isEmpty()){
                throw new \Exception('注销log记录失败');
            }
            $user->commit();

            return Response::SUCCESS;
        }catch (\Exception $e){
            Log::error("logoff error", $e->getMessage());
            $user->rollBack();
            return  Response::SYSTEM_ERROR;
        }
    }

    /**
     * @param $userId
     * @return bool
     */
    public static function logout($userId): bool
    {
        return (new JwtCache())->logout($userId);
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public static function getProfile($userId): ?array
    {
        $user = UserModel::field('mobile')->find($userId);
        if($user->isEmpty()){
            return null;
        }
        $data = $user->toArray();
        $data['userId'] = $userId;

        $vips = VipUserModel::field('vipTime')->where('userId',$userId)
            ->where('vipTime','>', time())
            ->find();
        $data['vips'] = $vips->toArray();

        return $data;
    }


}